/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.enums;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.annotation.JSONCreator;
import com.alibaba.fastjson2.annotation.JSONType;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(Currency)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/4/12
 */
@Getter
@NoArgsConstructor
@JSONType(writeEnumAsJavaBean = true)
public enum Currency implements Messageable {
    /** 为了对抗 Alibaba Java Coding 而存在的注释 */
    CNY("CNY", "人民币", "156"),
    MOP("MOP", "澳门元", "446"),
    HKD("HKD", "港币", "344"),
    TWD("TWD", "台币", "901"),
    USD("USD", "美元", "840"),
    JPY("JPY", "日元", "392"),
    EUR("EUR", "欧元", "978"),
    GBP("GBP", "英镑", "826"),
    AUD("AUD", "澳元", "036"),
    CAD("CAD", "加元", "124"),
    SGD("SGD", "坡币", "702"),
    NZD("NZD", "新西", "554"),
    KRW("KRW", "韩元", "410"),
    DKK("DKK", "丹朗", "208"),
    TRY("TRY", "土拉", "949"),
    MYR("MYR", "马来", "458"),
    THB("THB", "泰铢", "764"),
    INR("INR", "印卢", "356"),
    PHP("PHP", "菲比", "608"),
    CHF("CHF", "瑞士", "756"),
    SEK("SEK", "瑞典", "752"),
    ILS("ILS", "以谢", "376"),
    ZAR("ZAR", "南非", "710"),
    RUB("RUB", "俄卢", "643"),
    NOK("NOK", "挪威克朗", "578"),
    AED("AED", "阿联酋", "784"),
    BRL("BRL", "巴西雷亚尔", "986"),
    IDR("IDR", "印尼卢比", "360"),
    SAR("SAR", "沙特里亚尔", "682"),
    MXN("MXN", "墨西哥比索", "484"),
    PLN("PLN", "波兰兹罗提", "985"),
    VND("VND", "越南盾", "704"),
    CLP("CLP", "智利比索", "152"),
    KZT("KZT", "哈萨克腾格", "398"),
    CZK("CZK", "捷克克朗", "203"),
    NGN("NGN", "尼日利亚奈拉", "566"),
    COP("COP", "哥伦比亚比索", "170"),
    EGP("EGP", "埃及镑", "818"),
    VEF("VEF", "委玻利瓦尔", "937"),
    KWD("KWD", "科威特第纳尔", "414"),
    ARS("ARS", "阿根廷比索", "032"),
    RON("RON", "罗马尼亚列伊", "946"),
    QAR("QAR", "卡塔尔里亚尔", "634"),
    UAH("UAH", "乌格里夫纳", "980"),
    HUF("HUF", "匈牙利福林", "348"),
    PKR("PKR", "巴基斯坦卢比", "586"),
    LBP("LBP", "黎巴嫩镑", "422"),
    JOD("JOD", "约旦第纳尔", "400"),
    PEN("PEN", "秘鲁新索尔", "604"),

    /** 不晓得啷格回事 */
    ALL("ALL", "全币种", "Kaka king's Currency"),

    ;

    /** 枚举值 */
    private String code;

    /** 枚举描述 */
    private String message;

    /** 币种标识 */
    private String identify;


    /**
     * @param code     枚举值
     * @param message  枚举描述
     * @param identify 币种标识
     */
    Currency(String code, String message, String identify) {
        this.code = code;
        this.message = message;
        this.identify = identify;
    }

    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     *
     * @return Currency
     */

    public static Currency getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.getCode()))
                .findFirst().orElse(ALL);
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 枚举名
     *
     * @return CurrencyCurrency
     */
    public static Currency getByName(String name) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equalsIgnoreCase(name, innerEnum.name()))
                .findFirst().orElse(ALL);
    }

    @JSONCreator
    public static Currency deserialize(String code, String message, String identify) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.code()))
                .findFirst().orElse(ALL);
    }

    /**
     * 获取全部枚举
     *
     * @return List<Currency>
     */
    public static List<Currency> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(Currency::code).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {

        return Optional.ofNullable(code).map(
                str ->
                        Optional.ofNullable(getByCode(str))
                                .map(Currency::message).orElse(ALL.message())
        ).orElse(null);
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum 枚举
     *
     * @return code
     */
    public static String getCode(Currency innerEnum) {
        return Optional.ofNullable(innerEnum).map(Currency::code).orElse(ALL.code());
    }

    /**
     * map
     *
     * @return Map
     */
    public static Map<String, String> maps() {

        return Stream.of(values()).collect(Collectors.toMap(Currency::code, Currency::message));
    }

    /**
     * 判断给定的枚举，是否在列表中
     *
     * @param values 列表
     *
     * @return boolean
     */
    public boolean isInList(Currency... values) {
        for (Currency e : values) {
            if (this == e) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return Returns the code.
     */
    public String getCode() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    public String getMessage() {
        return message;
    }

    /**
     * @return Returns the code.
     */
    @Override
    public String code() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    @Override
    public String message() {
        return message;
    }

}